<template>
  <div class="uploading-list dialog">
    <transition name="fade">
      <div class="dialog-mask" v-show="visible"></div>
    </transition>

    <div class="dialog-wrap" :class="{'wrap--hide': !isWrapShow}" :style="wrapStyle" @click="onWrapClick">
      <div :class="{'dialog-center-fixed': !draggable}">
        <transition name="ease">
          <div class="dialog-confirm" :style="confirmStyle" v-show="visible">
            <div :class="contentClasses" :style="contentStyle" ref="content">
              <div class="header" @mousedown="handleMousedown">
                <h3 class="title">文件上传列表</h3>
                <a class="close" @click="close">
                  <i class="close-icon">x</i>
                </a>
              </div>
              <div class="body">
                <template v-if="uploadList.length">
                  <ul class="list">
                    <li
                      v-for="item in uploadList"
                      :key="item.key"
                      class="item"
                    >
                      <div class="item-inner">
                        <div class="icon" :class="formatFileTypeClasses(item.file.type)"></div>
                        <div class="file">
                          <div class="name">{{ item.file.name }}</div>
                          <div class="info">
                            <div class="size" v-if="item.status !== 3">
                              <span>{{ formatFileSize(item.file.size) }}</span>
                            </div>
                            <div class="progress-or-status">
                              <template v-if="item.status === 1">
                                <div class="progress">
                                  <div class="progress-rate" :style="{width: item.progress + '%'}"></div>
                                </div>
                              </template>
                              <span v-if="item.status === 0" class="prepare">等待中</span>
                              <span v-if="item.status === 3" class="error">
                                <span class="s1">上传失败</span>
                                <span class="s2" @click="$emit('on-re-upload', item.key)">点击重新上传</span>
                              </span>
                            </div>
                          </div>
                        </div>

                        <a class="item-abort" @click="$emit('on-remove', item.key)">
                          <!--                        <i class="close-icon"></i>-->
                          <span>删除</span>
                        </a>
                      </div>
                    </li>
                  </ul>
                </template>
                <template v-else>
                  <div class="is-completed">
                    <img src="../assets/img_empty.png" alt="">
                    <p>暂无上传内容</p>
                  </div>
                </template>
              </div>
              <div class="footer" v-if="false">
                <span class="close" @click="close">关闭</span>
              </div>
            </div>
          </div>
        </transition>
      </div>
    </div>
  </div>
</template>

<script>
import { formatFileSize, formatFileTypeClasses } from '../core/helper.js'

const _initDragData = () => ({
  x: null,
  y: null,
  dragX: null,
  dragY: null,
  dragging: false,
  rect: null
});

export default {
  props: {
    value: Boolean,

    draggable: {
      type: Boolean,
      default: false
    },
    sticky: {
      type: Boolean,
      default: true
    },
    stickyDistance: {
      type: Number,
      default: 10
    },

    uploadList: {
      type: Array,
      default: () => [
        {
          progress: 38,
          status: 1,
          file: {
            name: '喜欢你.mp3',
            size: 4356545,
            type: 'audio/mpeg'
          }
        },
        {
          progress: 0,
          status: 0,
          file: {
            name: '喜欢你.mp3',
            size: 4356545,
            type: 'audio/mpeg'
          }
        }
      ]
    }
  },
  data() {
    return {
      visible: this.value,
      isWrapShow: this.value,

      drag: _initDragData()
    }
  },
  computed: {
    wrapStyle() {
      return this.sticky ? {
        overflow: 'hidden'
      } : {}
    },
    confirmStyle() {
      return this.drag.x !== null ? {
        width: 'auto',
        top: 0
      } : {}
    },

    contentClasses() {
      return ['dialog-content', {'dialog-content--drag': this.draggable}]
    },
    contentStyle() {
      let style = {};

      if (this.draggable) {
        if (this.drag.x !== null) style.left = `${this.drag.x}px`;
        if (this.drag.y !== null) style.top = `${this.drag.y}px`;
      }

      return style;
    }
  },
  watch: {
    value(val) {
      this.visible = val;
    },
    visible(visible) {
      if (visible) {
        if (this.timer) clearTimeout(this.timer);

        this.isWrapShow = true;
        this.drag = _initDragData();
      } else {
        this.timer = setTimeout(() => {
          this.isWrapShow = false
        }, 300);
      }
    }
  },

  methods: {
    close() {
      this.visible = false;
      this.$emit('update:value', false);
    },
    onWrapClick(event) {
      // const className = event.target.getAttribute('class');
      // if (className && className.indexOf('dialog-wrap') > -1) this.close();
    },

    handleMousedown(e) {
      if (this.draggable === false) return false;

      const $content = this.$refs.content;
      const rect = $content.getBoundingClientRect();

      this.drag.rect = rect;
      this.drag.x = rect.x || rect.left;
      this.drag.y = rect.y || rect.top;

      const distance = {
        x: e.clientX,
        y: e.clientY
      };

      this.drag.dragX = distance.x;
      this.drag.dragY = distance.y;

      this.drag.dragging = true;

      window.addEventListener('mousemove', this.handleMousemove)
      window.addEventListener('mouseup', this.handleMouseup)
    },
    handleMousemove(e) {
      if (!this.drag.dragging) return false;

      const distance = {
        x: e.clientX,
        y: e.clientY
      };
      const diffDistance = {
        x: distance.x - this.drag.dragX,
        y: distance.y - this.drag.dragY
      };

      if (this.sticky) {
        const clientW = document.documentElement.clientWidth;
        const clientH = document.documentElement.clientHeight;

        if ((this.drag.x + diffDistance.x <= this.stickyDistance) && diffDistance.x < 0) {
          this.drag.x = 0;
        } else if ((this.drag.x + this.drag.rect.width - clientW > -this.stickyDistance) && diffDistance.x > 0) {
          this.drag.x = clientW - this.drag.rect.width;
        } else {
          this.drag.x += diffDistance.x;
        }

        if ((this.drag.y + diffDistance.y <= this.stickyDistance) && diffDistance.y < 0) {
          this.drag.y = 0;
        } else if ((this.drag.y + this.drag.rect.height - clientH > -this.stickyDistance) && diffDistance.y > 0) {
          this.drag.y = clientH - this.drag.rect.height;
        } else {
          this.drag.y += diffDistance.y;
        }
      } else {
        this.drag.x += diffDistance.x;
        this.drag.y += diffDistance.y;
      }

      this.drag.dragX = distance.x;
      this.drag.dragY = distance.y;
    },
    handleMouseup() {
      this.drag.dragging = false;

      window.removeEventListener('mousemove', this.handleMousemove);
      window.removeEventListener('mouseup', this.handleMouseup);
    },

    formatFileSize(size) {
      return formatFileSize(size);
    },
    formatFileTypeClasses(mimetype) {
      return formatFileTypeClasses(mimetype);
    }
  }
}
</script>

<style lang="scss" scoped>
@import "../index.scss";

.dialog-confirm {
  margin: 0 auto;
  width: 450px;
  top: 160px;
  position: relative;
}

.dialog-content {
  width: 450px;
  background-color: #FFF;
  border-radius: 5px;

  .header {
    position: relative;
    border-bottom: 1px solid #EAEAEA;
    user-select: none;

    .title {
      display: flex;
      align-items: center;
      padding: 0 20px;
      height: 45px;
      font-size: 16px;
      color: #111A38;
    }
    .close {
      height: 22px;
      width: 22px;
      position: absolute;
      right: 14px;
      top: 14px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;

      .close-icon {
        font-size: 0;
        height: 13px;
        width: 13px;
        background: url(../assets/icon_close.png) no-repeat;
        background-size: contain;
      }
    }
  }
  .footer {
    height: 40px;
    border-top: 1px solid #EAEAEA;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 0 10px;

    .close {
      cursor: pointer;
    }
  }
  .body {
    padding: 0 20px;
    height: 410px;
    overflow-y: auto;
    position: relative;

    .item {
      margin: 10px 0;
    }
    .item-inner {
      padding: 8px 10px;
      display: flex;
      align-items: center;
      background-color: #F8F8F8;
      border-radius: 4px;
      position: relative;
      user-select: none;

      .icon {
        flex: none;
        height: 32px;
        width: 32px;
        margin-right: 12px;
        background: url("../assets/ft_icon_default.png") no-repeat;
        background-size: contain;

        &.doc {
          background-image: url("../assets/ft_icon_doc.png")
        }
        &.xls {
          background-image: url("../assets/ft_icon_xls.png")
        }
        &.ppt {
          background-image: url("../assets/ft_icon_ppt.png")
        }
        &.pdf {
          background-image: url("../assets/ft_icon_pdf.png")
        }
        &.audio {
          background-image: url("../assets/ft_icon_mp3.png")
        }
        &.video {
          background-image: url("../assets/ft_icon_mp4.png")
        }
        &.image {
          background-image: url("../assets/ft_icon_img.png")
        }
      }
      .file {
        .name {
          max-width: 300px;
          line-height: 21px;
          font-size: 14px;
          color: #111A38;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .info {
          margin-top: 2px;
          line-height: 18px;
          font-size: 12px;
          color: #999;
        }
        .size {
          margin-right: 6px;
          line-height: 14px;
          color: #5293F5;
        }
        .progress-or-status {
          height: 18px;
          display: flex;
          align-items: center;

          .progress {
            height: 6px;
            width: 300px;
            background-color: #E1E0E5;
            border-radius: 3px;
          }
          .progress-rate {
            height: 100%;
            border-radius: 3px;
            background-color: #5293F5;
            transition: width .3s linear;
          }
          .error {
            display: flex;
            .s1 {
              margin-right: 10px;
              color: #FF7982;
            }
            .s2 {
              cursor: pointer;
              color: #5293F5;
            }
          }
        }
      }
      .item-abort {
        line-height: 22px;
        height: 22px;
        font-size: 12px;
        color: #FF7982;
        //width: 22px;
        position: absolute;
        right: 15px;
        top: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;

        .close-icon {
          font-size: 0;
          height: 11px;
          width: 11px;
          background: url(../assets/icon_close.png) no-repeat;
          background-size: contain;
        }
      }
    }

    .is-completed {
      height: 100px;
      width: 100px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      font-size: 14px;
      color: #555;
      text-align: center;
      img {
        width: 80%;
        vertical-align: middle;
      }
      p {
        margin-top: 8px;
        padding-right: 2px;
      }
    }

    &::-webkit-scrollbar {
      height: 0;
      width: 6px;
    }
    &::-webkit-scrollbar-thumb {
      background-color: #E1E0E5;
      border-radius: 3px;
    }
    &::-webkit-scrollbar-track {
      background: #FFF;
    }
  }
}
.dialog-content--drag {
  position: absolute;
  .header {
    cursor: move;
  }
}
</style>